#ifndef tlmRmtCfgSrvApp_H
#define tlmRmtCfgSrvApp_H

#include <wininet.h>

//## attribute mParaAdmin
#include "tlmRmtCfgParaAdmin.h"
//## attribute mParaNavi
#include "tlmRmtCfgParaNavi.h"
//## attribute mParaWeb
#include "tlmRmtCfgParaWeb.h"
//## class tlmRmtCfgSrvApp
#include "tlmServiceApp.h"
#include "ActiveClass.h"

#include <entISysEngineeringMode.h>
#include "entISysConfiguration.h"

//## operation OnReceiveMsg(tlmServiceMsg)
class tlmServiceMsg;


//## class tlmRmtCfgSrvApp
class tlmRmtCfgSrvApp : public tlmServiceApp, public ActiveClass{
    ////    Friends    ////
public:
    #define TLM_ACK_STATUS_OK 0
    #define TLM_ACK_STATUS_KO 1
    #define TLM_ACK_STATUS_OUTSIDE_LIMITS 2   

    #define TLM_RMT_CFG_MAX_RETRY_CNT 3

    #define TLM_RMT_CFG_TIMEOUT 6000 // Each tick is 20 ms - 120 sec timer
    #define TLM_RMT_CFG_SEND_MSG_TIMEOUT 1500 // Each tick is 20 ms - 30 sec timer

    #define TLM_RMT_CFG_RETRY_TIMEOUT 30000 // Each tick is 20 ms - 600 sec timer

    #define TLM_RMT_CFG_INIT_DELAY_TIMEOUT 150 // Each tick is 20 ms - 3 sec timer

    #define TLM_RMT_CFG_LANGUAGE_SIMPLE_CHINESE 10
    #define TLM_RMT_CFG_LANGUAGE_ENGLISH 1

    #define TLM_RMT_CFG_SET_SESSION_MASK 0x01
    #define TLM_RMT_CFG_GET_SESSION_MASK 0x02

public :


    ////    Constructors and destructors    ////
    
    tlmRmtCfgSrvApp();
    
    virtual ~tlmRmtCfgSrvApp();
	
	void initialize();
    
    ////    Operations    ////
    
    //## operation GetAckStatus()
    uint8_t GetAckStatus();
    
    //## operation GetInstance()
    static tlmRmtCfgSrvApp* GetInstance();

    void destroyInstance();
    
    //## operation GetParaAdmin()
    virtual tlmRmtCfgParaAdmin* GetParaAdmin();
    
    //## operation GetParaNavi()
    virtual tlmRmtCfgParaNavi* GetParaNavi();
    
    //## operation GetParaWeb()
    virtual tlmRmtCfgParaWeb* GetParaWeb();
    
    //## operation OnReceiveMsg(tlmServiceMsg)
    virtual void OnReceiveMsg(tlmServiceMsg* srvMsg);
    
    //## operation SaveParameters()
    uint8_t SaveParameters();
    
    //## operation SendMsg(tlmServiceMsg) const
    void SendMsg(tlmServiceMsg* msg) ;
    
    //## operation __OnReceiveMsg(tlmServiceMsg)
    void __OnReceiveMsg(tlmServiceMsg* srvMsg);
    
	
    void SendHttpMsg(uint8_t* msgPayload, uint32_t length); 

    void tlmRmtCfgSrvApp_makeAsyncCall(DWORD funcId,DWORD* pData,DWORD size);

    void CheckNewPendMsg(tlmServiceMsg* srvMsg) ; 
    void CheckNewGetCfgMsg(tlmServiceMsg* srvMsg) ;
    void onReceiveNewPendMsg(tlmServiceMsg* srvMsg);
    void onReceiveNewGetCfgMsg(tlmServiceMsg* srvMsg);
    void HandlePendingMsg(void); 
    void HandleGetCfgMsg(void);
    void SendConMsg(void);
    void SendParaMsg(void);
    void RequestConnection(uint8_t sessionMask) ;

    void OnReceiveHttpMsg(uint8_t* msgPayload, uint32_t length);
    void __OnReceiveHttpMsg(tlmServiceMsg* srvMsg);
    void HandleSetConfigMsg(void) ;
    void SendAckMsg(void);
    void OnGetCfgTimeOut(void);
    void OnSetCfgTimeOut(void);
    uint16_t GetGetCfgMsgId(void) const;
    uint16_t GetSetCfgMsgId(void) const;
    uint8_t* GetGenericVin(void) const;
        uint8_t* GetServiceVin(void) const;
        uint8_t GetLanguage(void) const;
        uint8_t* GetSwVersion(void) const;
        void CheckConnState(uint32_t status) const;

    void OnInitialization(void);
    void OnCheckUncompleteMsg(void);
    
    void CrackUrl(void);
    void InitParaAdmin(void);
    void InitParaWeb(void) ;
    void InitParaNavi(void) ;
    void InitVin(void) ;
    void UpdateGenericVin(const uint8_t * data);
    void UpdateImxSysInfo(const uint8_t * data);
    void UpdateLanguage(uint8_t  language);
    

    void OnCompleteSetCfg();

    void OnCompleteGetCfg();

    void OnGetCfgRetry();
    void OnSetCfgRetry();

    bool_t OpenHttpSession(HINTERNET& hSession, HINTERNET& hConnect,HINTERNET& hRequest) const;
    void CloseHttpSession(HINTERNET& hSession, HINTERNET& hConnect,HINTERNET& hRequest);

    bool_t GetHttpResponseData(HINTERNET hRequest);

    bool_t GetHttpResponseStatus(HINTERNET hRequest);
    
    
protected :
     /// operation __SyncCall(RPC_IOCTL_PTR)
     virtual void __SyncCall(RPC_IOCTL_PTR p);
 
     /// operation __AsyncCall(RPC_IOCTL_PTR)
     virtual void __AsyncCall(RPC_IOCTL_PTR p);    
	 
protected :

    uint8_t mAckStatus;		//## attribute mAckStatus
    
    tlmRmtCfgParaAdmin mParaAdmin;		//## attribute mParaAdmin
    
    tlmRmtCfgParaNavi mParaNavi;		//## attribute mParaNavi
    
    tlmRmtCfgParaWeb mParaWeb;		//## attribute mParaWeb

    tlmServiceMsg * mCurPendingMsg;
    tlmServiceMsg * mCurSetParaMsg;
    tlmServiceMsg * mCurGetCfgMsg;
    
    
    static tlmRmtCfgSrvApp* mpInstance;		//## attribute mpInstance

    uint8_t mConnSessionId;
    uint8_t mConnSessionFlag;

    uint32_t mSetSessionRetryCnt;
    uint32_t mGetSessionRetryCnt;

    uint8_t mGenericVin[TLM_GENERIC_VIN_LEN];

    uint8_t  SetMsgBuf[SIZE_ERG_DPCA_TLM_REMOTECFG_SET];
    uint8_t  GetMsgBuf[SIZE_ERG_DPCA_TLM_REMOTECFG_GET];  

    IMX_software_version mSysInfoImx;

    uint8_t mLanguage;

    LPTSTR mServerURL;
    LPTSTR mServerName;
    LPTSTR mServerUrlPath;
    URL_COMPONENTS mUrlComp;
};
#endif
